<?php
/**
 * 路由分派类
 * 完成URL解析、路由和调度
 *
 * @author vincent
 */
class Dispatcher {
	/**
	 * 路由分派
	 */
	public static function dispatch() {
		$segmentsTmp = array_filter ( explode ( '/', PATH_INFO ) );
		$uriSegments = array ();
		foreach ( $segmentsTmp as $tmp ) {
			$uriSegments [] = $tmp;
		}
		
		// 没有开启多模块
		if ($GLOBALS ['CONFIG'] ['MULTI_MODULE'] == false) {
			define ( 'MODULE_NAME', $GLOBALS ['CONFIG'] ['DEFAULT_MODULE'] ); // 使用默认的模块
			define ( "BASE_URL", APP_BASE_URL );
		}
		// 开启多模块但url上没有带上模块
		else if (count ( $uriSegments ) == 0 && $GLOBALS ['CONFIG'] ['MULTI_MODULE'] == true) {
			define ( 'MODULE_NAME', $GLOBALS ['CONFIG'] ['DEFAULT_MODULE'] ); // 使用默认的模块
			define ( "BASE_URL", APP_BASE_URL . '/' . $GLOBALS ['CONFIG'] ['DEFAULT_MODULE'] );
		}
		// 开启多模块且url上带模块
		else if ($GLOBALS ['CONFIG'] ['MULTI_MODULE'] == true && array_key_exists ( $uriSegments [0], $GLOBALS ['CONFIG'] ['URL_MODULE_MAP'] )) {
			define ( 'URL_MODULE_NAME', array_shift ( $uriSegments ) ); // url上的模块名
			define ( 'MODULE_NAME', $GLOBALS ['CONFIG'] ['URL_MODULE_MAP'] [URL_MODULE_NAME] );
			define ( "BASE_URL", APP_BASE_URL . '/' . URL_MODULE_NAME );
		}
		else {
			throw new Exception ( '模块' . $uriSegments [0] . '不存在', 404 );
		}
		
		// 模块的路径
		define ( 'MODULE_PATH', APPLICATION_PATH . '/' . MODULE_NAME );
		
		// 加载模块下的配置文件
		if (file_exists ( MODULE_PATH . '/common/config.php' )) {
			$GLOBALS ['CONFIG'] = array_merge ( $GLOBALS ['CONFIG'], include MODULE_PATH . '/common/config.php' );
		}
		
		// 是否开启自定义路由
		if ($GLOBALS ['CONFIG'] ['URL_ROUTER_ON'] == true) {
			// 自定义路由是否匹配成功
			if (self::parseRule ( $uriSegments ) === false) {
				self::parseUrl ( $uriSegments );
			}
		}
		// 使用默认路由规则
		else {
			self::parseUrl ( $uriSegments );
		}
	}
	
	/**
	 * 解析url
	 *
	 * @param array $uriSegments module后的uri分段
	 */
	private static function parseUrl($uriSegments) {
		$controller = (count ( $uriSegments ) > 0) ? array_shift ( $uriSegments ) : $GLOBALS ['CONFIG'] ['DEFAULT_CONTROLLER'];
		$action = (count ( $uriSegments ) > 0) ? array_shift ( $uriSegments ) : $GLOBALS ['CONFIG'] ['DEFAULT_ACTION'];
		define ( 'CONTROLLER_NAME', self::getControllerName ( $controller ) );
		define ( 'ACTION_NAME', self::getACtionName ( $action ) );
	}
	/**
	 * 解析自定义路由规则
	 *
	 * @param array $uriSegments module后的uri分段
	 * @return boolean
	 */
	private static function parseRule($uriSegments) {
		// 路由规则
		$routes = $GLOBALS ['CONFIG'] ['URL_ROUTE_RULES'];
		$uriSegmentLen = count ( $uriSegments );
		foreach ( $routes as $rule => $route ) {
			$ruleSegments = array_filter ( explode ( '/', $rule ) );
			$len = count ( $ruleSegments );
			if ($len != $uriSegmentLen) {
				continue;
			}
			
			$params = array ();
			for($index = 0; $index < $len; $index ++) {
				$pos = strpos ( $ruleSegments [$index], ':' ); // 判断是否为参数
				if ($pos === false && $ruleSegments [$index] != $uriSegments [$index])
					break;
				
				if ($pos === 0)
					$params [substr ( $ruleSegments [$index], 1 )] = $uriSegments [$index];
			}
			if ($index == $len) {
				self::parseUrl ( array_filter ( explode ( '/', $route ) ) );
				$_GET = array_merge ( $_GET, $params );
				return true;
			}
		}
		
		return false;
	}
	
	/**
	 * 获取controller的类名
	 *
	 * @param string $controller
	 */
	public static function getControllerName($controller) {
		return ucfirst ( $controller ) . 'Controller';
	}
	/**
	 * 获取action名
	 *
	 * @param string $controller
	 */
	public static function getActionName($action) {
		return $action . 'Action';
	}
}
